package com.infinit.selfhelp.common.widget

import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.animation.Animation
import android.view.animation.AnimationUtils
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import com.infinit.selfhelp.common.R
import com.infinit.selfhelp.common.databinding.WidgetViewMessageTopBinding
import com.infinit.selfhelp.common.ext.gotoActionDialOrEmailStart
import com.infinit.selfhelp.common.ext.show
import com.infinit.selfhelp.common.utils.TextViewSpannableUtils

class CommonMessageView constructor(context: Context, attrs: AttributeSet?) : ConstraintLayout(context, attrs) {
    var mDuration: Long = -1
    var action: String? = null
    private var binding: WidgetViewMessageTopBinding = WidgetViewMessageTopBinding.inflate(LayoutInflater.from(context), this, true)

    private val durationTop: Long = 3000

    init {
        this.visibility = View.GONE
        binding.ivClose.setOnClickListener { dismiss() }
        binding.tvMessage.setOnClickListener {
            clickableMessageViewCallBack.invoke()
        }

        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CommonMessageView)
        val boolean = typedArray.getBoolean(R.styleable.CommonMessageView_right_close_show, false)
        typedArray.recycle()
        binding.ivClose.isVisible = boolean
    }

    fun setIconMessage(message: String, iconType: Int = iconTypeNegative) {
        setIconResource(iconType)
        setMessage(message, durationTop)
        binding.ivIcon.show()
    }

    fun setIconMessage(message: String, iconType: Int = iconTypeNegative, isAutoLink: Boolean, action: String = "") {
        setIconResource(iconType)
        setMessage(message, durationTop, action)
        binding.ivIcon.show()
    }

    fun setIconMessage(id: Int, iconType: Int = iconTypeNegative) {
        setIconResource(iconType)
        setMessage(id, durationTop)
        binding.ivIcon.show()
    }

    fun setCloseMessage(message: String) {
        mDuration = -1
        binding.ivClose.show()
        binding.tvMessage.text = message
        show()
    }

    private fun setIconResource(iconType: Int) {
        when (iconType) {
            iconTypeNegative -> binding.ivIcon.setImageResource(R.drawable.ic_message_error)
            iconTypePositive -> binding.ivIcon.setImageResource(R.drawable.ic_message_right)
            iconTypeWarn -> binding.ivIcon.setImageResource(R.drawable.ic_message_warning)
        }
    }

    fun setActionText(action: String?) {
        this.action = action
    }

    fun setMessage(message: String) {
        if (!action.isNullOrBlank() && message.contains(action!!)) {
            TextViewSpannableUtils.setSpannable(
                message,
                action!!,
                Color.parseColor("#FF7702"),
                binding.tvMessage,
            )
            mDuration = -1
            binding.ivClose.show()
        } else {
            binding.tvMessage.text = message
        }

        show()
    }

    fun setMessage(message: String, duration: Long, action: String = "") {
        mDuration = duration
        context.gotoActionDialOrEmailStart(message, binding.tvMessage, action) {
            if (it) {
                clickableMessageViewCallBack()
            }
            mDuration = -1
            binding.ivClose.show()
        }
        show()
    }

    fun setMessage(id: Int) {
        setMessage(resources.getString(id))
    }

    fun setMessage(message: String, duration: Long) {
        mDuration = duration
        setMessage(message)
    }

    fun setMessage(id: Int, duration: Long) {
        mDuration = duration
        setMessage(id)
    }

    fun setMessage(message: String, duration: Long, callback: () -> Unit) {
        setMessage(message, duration)
        clickableMessageViewCallBack = callback
    }

    fun setMessage(id: Int, duration: Long, callback: () -> Unit) {
        setMessage(id, duration)
        clickableMessageViewCallBack = callback
    }

    fun setMessage(message: String, callback: () -> Unit) {
        setMessage(message)
        clickableMessageViewCallBack = callback
    }

    fun setMessage(id: Int, callback: () -> Unit) {
        setMessage(id)
        clickableMessageViewCallBack = callback
    }

    fun setNormalMessage(message: String) {
        setMessage(message, durationTop)
    }

    fun setNormalMessage(id: Int) {
        setMessage(id, durationTop)
    }

    fun show() {
        if (isVisible.not()) {
            visibility = View.VISIBLE
            createInAnim()
        }
    }

    fun dismiss() {
        if (visibility == View.GONE) return
        val mSlideOutAnimation = AnimationUtils.loadAnimation(
            context,
            R.anim.slide_up_out,
        )

        mSlideOutAnimation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                visibility = View.GONE
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        startAnimation(mSlideOutAnimation)
    }

    private fun createInAnim() {
        val mSlideInAnimation = AnimationUtils.loadAnimation(context, R.anim.slide_down_in)
        mSlideInAnimation.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation) {}
            override fun onAnimationEnd(animation: Animation) {
                if (mDuration < 0) {
                    return
                }
                postDelayed({ dismiss() }, mDuration)
            }

            override fun onAnimationRepeat(animation: Animation) {}
        })
        animation = mSlideInAnimation
    }

    var clickableMessageViewCallBack: () -> Unit = {}

    companion object {
        const val iconTypeDefault = 0
        const val iconTypeNegative = 1
        const val iconTypePositive = 2
        const val iconTypeWarn = 3
    }
}
